package com.m3958.firstgwt.server.command;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import net.sf.json.JSONObject;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.inject.Inject;
import com.m3958.firstgwt.client.types.ActiveMqSubject;
import com.m3958.firstgwt.client.types.SmartSubOperationName;
import com.m3958.firstgwt.server.exception.SmartJpaException;
import com.m3958.firstgwt.server.model.BaseModel;
import com.m3958.firstgwt.server.model.WFChangeLog;
import com.m3958.firstgwt.server.model.WebSite;
import com.m3958.firstgwt.server.response.ErrorMessageResponse;
import com.m3958.firstgwt.server.service.MyActiveMqProducerService;
import com.m3958.firstgwt.server.service.SiteConfiger;
import com.m3958.firstgwt.server.service.SiteConfiger.SiteConfigerKeyName;

public class AddCommand extends BaseCommand implements Command{
	
	private boolean writeResponse = true;
	
	@Inject
	private SiteConfiger siteConfiger;
	
	JSONObject result = null;
	
	@Override
	public void execute() throws SmartJpaException, IOException{
		SmartSubOperationName sson = SmartSubOperationName.NO_SUB_OPERATION;
		if(reqPs.getSubOpType() != null)
			sson = SmartSubOperationName.valueOf(reqPs.getSubOpType());
		
		switch (sson) {
		default:
			result = smartAdd();
		}
		if(writeResponse){
			JSONObject m3958jo = new JSONObject();
			m3958jo.element("tid", reqPs.getTid());
			if(!errors.isEmpty()){
				result = injector.getInstance(ErrorMessageResponse.class).getJsonObject();
			}
			result.getJSONObject("response").element("m3958extra", m3958jo);
			
			if(reqPs.isJsonp()){
				autils.writeJsonpResponse(res, result.toString(), reqPs.getStringValue("callback"));
			}else{
				if(reqPs.isIframe()){
					irss.addIframeResult(reqPs.getTid(), result.toString());
					autils.writeHtmlResponseWithTemplate(res, "", "");
				}else{
					autils.writeJsonResponse(res,result.toString());
				}
			}
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private JSONObject smartAdd() throws SmartJpaException{
		if("com.m3958.firstgwt.server.model.AsyncTask".equals(reqPs.getModelName())){
			File cd = new File(siteConfiger.getValue(SiteConfigerKeyName.CAMEL_INTERCHANGE_DIR));
			cd = new File(cd,"clonepage-" + UUID.randomUUID().toString() + ".json");
			JSONObject jo = JSONObject.fromObject(reqPs.getStringValue("taskDescript"));
			String rp = jo.getString("path");
			int siteid = jo.getInt("siteId");
			WebSite ws = emp.get().find(WebSite.class, siteid);
			File themeroot = ws.getThemeRoot(siteConfiger.getValue(SiteConfigerKeyName.SITE_ROOT),rp);
			jo.element("path", themeroot.getAbsolutePath());
			try {
				Files.write(jo.toString(), cd, Charsets.UTF_8);
			} catch (IOException e) {}
		}
		if("com.m3958.firstgwt.server.model.WFChangeLog".equals(reqPs.getModelName())){
			return processWFCLog();
		}
		BaseModel model = getBaseModelFromParams();
		getDao().smartPersistBaseModel(model);
		return autils.getListResponse(model,reqPs.getJsonv());
	}
	
	private JSONObject processWFCLog() throws SmartJpaException {
		res.setHeader("Cache-Control","no-cache, must-revalidate");
		if(reqPs.getBooleanValue("shared")){
			return processSharedWFCLog();
		}
		String cl = reqPs.getStringValue("changeDelta");
		int clientLastTransId = reqPs.getIntegerValue("lastTransId");
		List<WFChangeLog> wfcls;
		if(clientLastTransId == 0){
			wfcls = new ArrayList<WFChangeLog>();
		}else{
			wfcls = emp.get().createNamedQuery(WFChangeLog.NamedQueries.FIND_USER_LOG_AFTER_ME).setParameter(1, clientLastTransId).getResultList();
		}
		//有冲突，不保存结果。
		JSONObject jo;
		if(wfcls.size() > 0){
			jo = autils.getListResponse(wfcls,0,wfcls.size(),reqPs.getJsonv());
			jo.getJSONObject("response").element("collide", true);
			jo.getJSONObject("response").element("lastTransId", wfcls.get(wfcls.size()-1).getId());
			return jo;
		}else{
			if("[]".equals(cl)){
				jo = autils.getEmptyListResponse();
				jo.getJSONObject("response").element("collide", false);
				return jo;
			}else{
				MyActiveMqProducerService mm = injector.getInstance(MyActiveMqProducerService.class);
				mm.sendTextMessage(ActiveMqSubject.WF_CHANGE_LOG, cl);
			}
			BaseModel model = getBaseModelFromParams();
			getDao().smartPersistBaseModel(model);
			jo = autils.getListResponse(model,reqPs.getJsonv());
			jo.getJSONObject("response").element("collide", false);
			jo.getJSONObject("response").element("lastTransId", model.getId());
			return jo;
		}
	}

	private JSONObject processSharedWFCLog() throws SmartJpaException {
		String cl = reqPs.getStringValue("changeDelta");
		String mid = reqPs.getStringValue("mid");
		if(mid == null || mid.length() < 32){
			mid = "none-existed-mid";
		}
		int clientLastTransId = reqPs.getIntegerValue("lastTransId");
		List<WFChangeLog> wfcls;
		if(clientLastTransId == 0){
			wfcls = new ArrayList<WFChangeLog>();
		}else{
			wfcls = emp.get().createNamedQuery(WFChangeLog.NamedQueries.FIND_ITEM_LOG_AFTER_ME).setParameter(1, clientLastTransId).setParameter(2, "%" + mid + "%").getResultList();
		}
		
		//有冲突，不保存结果。
		JSONObject jo;
		if(wfcls.size() > 0){
			jo = autils.getListResponse(wfcls,0,wfcls.size(),reqPs.getJsonv());
			jo.getJSONObject("response").element("collide", true);
			jo.getJSONObject("response").element("lastTransId", wfcls.get(wfcls.size()-1).getId());
			return jo;
		}else{
			if("[]".equals(cl)){
				jo = autils.getEmptyListResponse();
				jo.getJSONObject("response").element("collide", false);
				return jo;
			}else{
				MyActiveMqProducerService mm = injector.getInstance(MyActiveMqProducerService.class);
				mm.sendTextMessage(ActiveMqSubject.WF_CHANGE_LOG, cl);
			}
			BaseModel model = getBaseModelFromParams();
			getDao().smartPersistBaseModel(model);
			jo = autils.getListResponse(model,reqPs.getJsonv());
			jo.getJSONObject("response").element("collide", false);
			jo.getJSONObject("response").element("lastTransId", model.getId());
			return jo;
		}
	}

	/**
	 * 必须传入当前的tableschema，还有req
	 * @return
	 */
//	private JSONObject clojureAdd() {
//		TableSchema ts = emp.get().find(TableSchema.class, reqPs.getTableschemaid());
//		if(ts == null){
//			errors.addError(new SmartError("必须提供表单结构Id号！", 0));
//			return null;
//		}
////		return autils.getListResponse(JSONObject.fromObject(clojureService.getAddResult(req,ts)), reqPs.getJsonv());
//		return JSONObject.fromObject(clojureService.getAddResult(req,ts));
//	}

	@Override
	public String getResult() {
		return result.toString();
	}

	@Override
	public void execute(boolean writeResponse) throws SmartJpaException,
			IOException {
		this.writeResponse = writeResponse;
		execute();
	}

}
